<?php
    $base_path = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    $bit_check = array(4=>3, 8 => 4, 16 => 5, 32 => 6, 64 => 7, 128 => 8, 256 => 9);
    
    function getParam($name) {
        if (isset($_GET[$name])) return $_GET[$name];
        else if (isset($_POST[$name])) return $_POST[$name];
    }
    
    function generateChecksBits($bits, $value, $value_error = null) {
        global $bit_check;
        $arr_bits = generateBits($bits);
        
        $arr_check = array();
        $arr_check_hold = array();
        
        $arr_data = array();
        $arr_data_hold = array();
        $arr_data_hold2 = array();
        
        $arr_true_xor = array();
        $arr_false_xor = array();
        
        $arr_data_with_check = array();
        for ($i = count($arr_bits); $i > 0 ; $i--) {
            if (substr_count($arr_bits[$i-1],'1') == 1) {
                $arr_check[] = $arr_bits[$i-1];
                $arr_check_hold[] = $i;
            } else {
                $arr_data[] = $arr_bits[$i-1];
                $arr_data_hold[] = $i;
            }
        }
        
        $i = 0;
        for($k = count($arr_data); $k > 0; $k--, $i++) {
            $arr_data_hold2[$k] = $arr_data_hold[$i];
        }
        
        $j = 1;
        for($i = count($arr_check); $i > 0; $i--, $j++) {
            $position = strpos($arr_check[$i-1], '1');
            $l = 1;
            for($k = count($arr_data); $k > 0; $k--, $l++) {
                $arr_checker = str_split($arr_data[$k-1]);
                if($arr_checker[$position] == 1) {
                    $arr_data_with_check[$j][] = $l;
                }
            }
        }
			echo "<b>Perhitungan Jumlah Bit</b><br />";
		echo "<b>2<sup>k</sup> - 1 >= M+K</b><br />";
		$k = 0;
		$flag = 0;
		for($cnt=2;$cnt<=$bits; $cnt++){
			if ($flag) continue;
			$ss = (pow(2,$cnt) - 1);
			if ($ss >= ($bits + $cnt) ){
				$k = $cnt;
				$flag = 1;
			}
		}
		echo "2<sup>".$k."</sup> - 1 >= ".$bits."+".$k." <br />";
		echo (pow(2,$k) - 1)." >= ".($bits + $k) ." <br />";
        echo "<br />";
		
        echo "<b>Formula untuk Pengujian Bit</b><br />";
        $key_check = count($arr_check_hold);
        foreach($arr_data_with_check as $key => $item) {
            echo "C".$arr_check_hold[$key_check - $key]." = ";
            for($i = 0; $i < count($item); $i++) {
                echo "D".$item[$i];
                if ($i < (count($item) - 1)) echo " &oplus; ";
            }
            echo "<br />";
        }
        
        echo "<br />";
	
        
        
        //SHIFT ARR_CHECK_HOLD
        $arr_check_hold2 = $arr_check_hold;
        for($i=0;$i<(int)(count($arr_check_hold2)/2);$i++) {
            $temp = $arr_check_hold2[$i];
            $arr_check_hold2[$i] = $arr_check_hold2[count($arr_check_hold2)-(1+$i)];
            $arr_check_hold2[count($arr_check_hold2)-(1+$i)] = $temp;
        }
        
        //SHIFT ARR_DATA_HOLD
        $arr_data_hold2 = $arr_data_hold;
        for($i=0;$i<(int)(count($arr_data_hold2)/2);$i++) {
            $temp = $arr_data_hold2[$i];
            $arr_data_hold2[$i] = $arr_data_hold2[count($arr_data_hold2)-(1+$i)];
            $arr_data_hold2[count($arr_data_hold2)-(1+$i)] = $temp;
        }
        
        $key_check = count($arr_check_hold);
        $arr_value_split = str_split($value);
        
        for($i=0;$i<(int)(count($arr_value_split)/2);$i++) {
            $temp = $arr_value_split[$i];
            $arr_value_split[$i] = $arr_value_split[count($arr_value_split)-(1+$i)];
            $arr_value_split[count($arr_value_split)-(1+$i)] = $temp;
        }
        
        $arr_value = array();
        foreach ($arr_check_hold2 as $key => $item) {
            $arr_value[$item-1] = '0';
        }
        foreach ($arr_data_hold2 as $key => $item) {
            $arr_value[$item-1] = $arr_value_split[$key];
        }
        ksort($arr_value);
        
        echo "<b>Pengecekan untuk bit dari Biner yang benar</b><br />";
        foreach($arr_data_with_check as $keys => $item) {
            echo "C".$arr_check_hold[$key_check - $keys]." = ";
            $xor_value = false;
            for($i = 0; $i < count($item); $i++) {
                $key = $arr_data_hold2[($item[$i]-1)];
                echo $arr_value[($key-1)];
                
                if ($i > 0) $xor_value = ($xor_value xor $arr_value[($key-1)]);
                else $xor_value = $arr_value[($key-1)];
                        
                if ($i < (count($item) - 1)) echo " &oplus; ";
            }
            echo " = ".($xor_value ? '1' : '0');
            $arr_true_xor[] = $xor_value;
            $arr_value[(($arr_check_hold[$key_check - $keys])-1)] = ($xor_value ? '1' : '0');
            echo "<br />";
        }
        
        echo "<br />";
           $arr_value_err = array();
        $array_diff = null;
        if (!is_null($value_error)) {
            $arr_value_split_err = str_split($value_error);
        
            for($i=0;$i<(int)(count($arr_value_split)/2);$i++) {
                $temp = $arr_value_split_err[$i];
                $arr_value_split_err[$i] = $arr_value_split_err[count($arr_value_split_err)-(1+$i)];
                $arr_value_split_err[count($arr_value_split_err)-(1+$i)] = $temp;
            }
            
            $array_diff = array_diff_assoc($arr_value_split, $arr_value_split_err);
            $array_diff = array_keys($array_diff);
            $array_diff = ($array_diff[0]+1);
            
         
            foreach ($arr_check_hold2 as $key => $item) {
                $arr_value_err[$item-1] = '0';
            }
            foreach ($arr_data_hold2 as $key => $item) {
                $arr_value_err[$item-1] = $arr_value_split_err[$key];
            }
            ksort($arr_value_err);
            
            echo "<b>Pengecekan untuk bit dari Biner yang salah</b><br />";
            foreach($arr_data_with_check as $keys => $item) {
                echo "C".$arr_check_hold[$key_check - $keys]." = ";
                $xor_value = false;
                for($i = 0; $i < count($item); $i++) {
                    $key = $arr_data_hold2[($item[$i]-1)];
                    echo $arr_value_err[$key - 1];
                    
                    if ($i > 0) $xor_value = ($xor_value xor $arr_value_err[$key - 1]);
                    else $xor_value = $arr_value_err[$key - 1];
                    
                    if ($i < (count($item) - 1)) echo " &oplus; ";
                }
                echo " = ".($xor_value ? '1' : '0');
                $arr_false_xor[] = $xor_value;
                $arr_value_err[(($arr_check_hold[$key_check - $keys])-1)] = ($xor_value ? '1' : '0');
                echo "<br />";
            }
        }
        echo "<br />";
        
        echo "<b>Pengecekan Bit</b><br />";
        echo "<table border='1' class='tableStd'><tr>";
        if (count($arr_false_xor) > 0) echo "<td rowspan='4' valign='bottom'>&oplus;</td>";
        foreach($arr_data_with_check as $keys => $item) {
                echo "<td>C".$arr_check_hold[$key_check - $keys]."</td>";
        }
        echo "</tr><tr>";
        for($i = 0; $i < count($arr_true_xor); $i++) {
            echo "<td>".($arr_true_xor[$i] ? '1' : '0')."</td>";
        }
        echo "</tr><tr>";
        for($i = 0; $i < count($arr_false_xor); $i++) {
            echo "<td>".($arr_false_xor[$i] ? '1' : '0')."</td>";
        }
        echo "</tr><tr>";
        for($i = 0; $i < count($arr_false_xor); $i++) {
            echo "<td>".(($arr_true_xor[$i] xor $arr_false_xor[$i]) ? '1' : '0')."</td>";
        }
        echo "</tr></table><br />";
        
        if (!is_null($array_diff)) echo "<b>Kesalahan terdapat pada D".$array_diff."</b><br /><br />";
        
        for($i=0;$i<(int)(count($arr_value)/2);$i++) {
            $temp = $arr_value[$i];
            $arr_value[$i] = $arr_value[count($arr_value)-(1+$i)];
            $arr_value[count($arr_value)-(1+$i)] = $temp;
        }
        
        for($i=0;$i<(int)(count($arr_value_err)/2);$i++) {
            $temp = $arr_value_err[$i];
            $arr_value_err[$i] = $arr_value_err[count($arr_value_err)-(1+$i)];
            $arr_value_err[count($arr_value_err)-(1+$i)] = $temp;
        }
        
        $result = array("errorBinaryChecker" => $arr_value, 
                        "errorBinary" => $arr_value_err, 
                        "array_diff" => $array_diff);
        
        return $result;
    }
    
    function generateHammingCodeTable($bits, $value, $value_error = null,  $error_position = null) {
        global $bit_check;
        $arr_bits = generateBits($bits);
        
        // GENERATE HTML TABLE
        echo "<b>Tabel Hamming Code</b><br />";
        echo "<table border='1' class='tableStd' style='margin-bottom:20px;'>";
        echo "<tr>";
        echo "<td nowrap='nowrap' style='min-width:110px;'>Posisi Bit</td>";
        for ($i = count($arr_bits); $i >= 1 ; $i--)
            echo "<td class='td".$i."'>".($i)."</td>";
        echo "</tr>";
        echo "<tr>";
        echo "<td>Biner Posisi</td>";
        for ($i = count($arr_bits); $i > 0 ; $i--)
            echo "<td class='td".$i."'>".$arr_bits[$i-1]."</td>";
        echo "</tr>";
        echo "<tr>";
        echo "<td>Bit Data</td>";
        $j = $bits;
        for ($i = count($arr_bits); $i > 0 ; $i--) {
            if (substr_count($arr_bits[$i-1],'1') > 1) {
                if (!is_null($error_position) && $error_position == $j) echo "<td id='error' class='td".$i."'>D".$j."</td>";
                else  echo "<td class='td".$i."'>D".$j."</td>";
                $j--;
            } else {
                echo "<td class='td".$i."'></td>";
            }
        }
        echo "</tr>";
        echo "<tr>";
        echo "<td>Bit Check</td>";
        for ($i = count($arr_bits); $i > 0 ; $i--) {
            if (substr_count($arr_bits[$i-1],'1') == 1) {
                echo "<td class='td".$i."'>C".$i."</td>";
            } else {
                echo "<td class='td".$i."'></td>";
            }
        }
        echo "</tr>";
        echo "<tr>";
        echo "<td>Biner Benar</td>";
        $arr_value = str_split($value);
        $j = count($arr_bits);
        for ($i = 0; $i < count($arr_bits) ; $i++, $j--) {
            echo "<td class='td".$j."'>".$arr_value[$i]."</td>";
        }
        echo "</tr>";
        if (!is_null($value_error)) {
            echo "<tr>";
            echo "<td>Biner Salah</td>";
            $arr_value = str_split($value_error);
            $j = count($arr_bits);
            for ($i = 0; $i < count($arr_bits) ; $i++, $j--) {
                echo "<td class='td".$j."'>".$arr_value[$i]."</td>";
            }
            echo "</tr>";
        }
        echo "</table><br />";
    }
    
    function generateBits($bits) {
        global $bit_check;
        $arr_bits = array();
        for($i=1;$i<=$bits+$bit_check[$bits];$i++) {
            $arr_bits[] = sprintf("%1$0".$bit_check[$bits]."d",decbin($i));
        }
        return $arr_bits;
    }
    
    function validateInput($arr_true, $arr_false) {
        $array_true = str_split($arr_true);
        $array_false = str_split($arr_false);
        $return = true;
        $array_result = array_diff_assoc($array_true, $array_false);
        $error = array();
        
        if (count($array_result) > 1) 
            $error[] = "Tidak boleh melakukan penggantian bit lebih dari satu";
            
        if (strlen($arr_true) > strlen($arr_false) || strlen($arr_true) < strlen($arr_false))
            $error[] = "Tidak boleh melakukan pengurangan atau penambahan bit";
        
        if (count($error) > 0) $return = false;
        
        $result = array("error" => $error, "return" => $return);
        return $result;
    }
    
    function errorPage($errorMessage) {
        echo "<div id='errorBox'>";
        echo "<h3>Kesalahan : </h3>";
        foreach($errorMessage as $error) echo "- ".$error."<br />";
        echo "</div>";
    }